#define _CRT_SECURE_NO_WARNINGS 1
#include"string.h"
using namespace std;
namespace bit
{
    void string::reserve(size_t n)
    {
        if (n > _capacity)
        {
            char* tmp = new char[n + 1];
            strcpy(tmp, _str);
            delete[] _str;
            _str = tmp;
            _capacity = n;
        }

    }
    void string::push_back(char c)
    {
        if (_capacity == _size)
        {
            reserve(_capacity == 0 ? 4 : 2 * _capacity);
        }
        _str[_size++] = c;
        _str[_size + 1] = '\0';
    }

    string& string::operator+=(char c)
    {
        push_back(c);
        return *this;
    }

    void string::append(const char* str)
    {

        size_t len = strlen(str);
        if (len + _size >= _capacity)
        {
            reserve(len + _size > _capacity ? len + _size : _capacity * 2);
        }

        strcpy(_str + _size, str);
        _size += len;
    }

    string& string::operator+=(const char* str)
    {
        append(str);
        return *this;
    }

    string& string::insert(size_t pos, char c)
    {
        if (_size + 1 > _capacity)
        {
            reserve(2 * _capacity);
        }
        size_t end = _size;
        size_t cur = _size - 1;
        while (cur >= pos)
        {
            _str[end--] = _str[cur--];
        }
        _str[pos] = c;
        _size += 1;
        return *this;
    }

    string& string::insert(size_t pos, const char* str)
    {
        size_t len = strlen(str);
        if (_size + strlen(str) > _capacity)
        {
            reserve(2 * _capacity);
        }
        size_t end = _size+len-1;
        size_t cur = _size - 1;
        while (cur >= pos)
        {
            _str[end--] = _str[cur--];
        }
        int i = 0;
        while (pos <= end)
        {
            _str[pos++] = str[i++];
        }
        _str[_size + len] = '\0';
        _size += len;
        return *this;
    }

    string& string::erase(size_t pos, size_t len)
    {
        
        if (pos + len >= _size)
        {
            _str[pos] = '\0';
            _size -= len;
            return *this;
        }
        size_t cur = pos + len;
        size_t pre = pos;
        
        while (cur < _size)
        {
            _str[pre++] = _str[cur++];
        }
        _str[pre] = '\0';
        _size -= len;
        return *this;
    }

    void string::resize(size_t n, char c )
    {
        
        if (n > _size)
        {
            for (int i = _size; i < n; i++)
            {
                _str[i] = c;
            }        
        }
        _str[n] = '0';
        _size = n;
    }

    size_t string::find(char c, size_t pos) const
    {
        assert(pos < _size);
        for (size_t i = 0; i < _size; i++)
        {
            if (_str[i] == c)
                return i;
        }
        return std::string::npos;
    }

    size_t string::find(const char* s, size_t pos) const
    {
        assert(pos < _size);
        const char* ret = strstr(_str+pos, s);
        if (ret == NULL)
            return npos;
        else
        {
            return ret-_str;
        }
    }
}
